#ifndef _SPI_FLASH_H
#define _SPI_FLASH_H

#ifdef __cplusplus
 extern "C" {
#endif
#include "main.h"


#define SPI_TIMEOUT_MAX			1000
/**
  * @brief  M25P FLASH SPI Control Interface pins
  */
#define SPI_FLASH_CS_PIN                           GPIO_PIN_12        /* PB.02*/
#define SPI_FLASH_CS_GPIO_PORT                     GPIOB
#define SPI_FLASH_CS_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOB_CLK_ENABLE()
#define SPI_FLASH_CS_GPIO_CLK_DISABLE()            __HAL_RCC_GPIOB_CLK_DISABLE()
/**
  * @brief  M25P FLASH SPI Chip Select macro definition 
  */
#define SPI_FLASH_CS_LOW()       HAL_GPIO_WritePin(SPI_FLASH_CS_GPIO_PORT, SPI_FLASH_CS_PIN, GPIO_PIN_RESET)
#define SPI_FLASH_CS_HIGH()      HAL_GPIO_WritePin(SPI_FLASH_CS_GPIO_PORT, SPI_FLASH_CS_PIN, GPIO_PIN_SET)
/**
  * @brief  M25P FLASH SPI supported commands
  */  
#define SPI_FLASH_CMD_WRITE          0x02  /*!< Write to Memory instruction */
#define SPI_FLASH_CMD_WRSR           0x01  /*!< Write Status Register instruction */
#define SPI_FLASH_CMD_WREN           0x06  /*!< Write enable instruction */
#define SPI_FLASH_CMD_READ           0x03  /*!< Read from Memory instruction */
#define SPI_FLASH_CMD_RDSR           0x05  /*!< Read Status Register instruction  */
#define SPI_FLASH_CMD_RDID           0x9F  /*!< Read identification */
#define SPI_FLASH_CMD_SE             0x20  /*!< Sector Erase instruction */
#define SPI_FLASH_CMD_BE             0xC7  /*!< Bulk Erase instruction */

#define SPI_FLASH_WIP_FLAG           0x01  /*!< Write In Progress (WIP) flag */

#define SPI_FLASH_DUMMY_BYTE         0xA5
#define SPI_FLASH_PAGESIZE           0x100
#define SPI_FLASH_SECTORSIZE	     0x1000

#define SPI_FLASH_W25Q256_ID         0xEF4019
#define SPI_FLASH_W25Q128_ID         0xEF4018
#define SPI_FLASH_W25Q64_ID          0xEF4017
#define SPI_FLASH_W25Q32_ID          0xEF4016
#define SPI_FLASH_W25Q16_ID			 0xEF4015
#define SPI_FLASH_W25Q8_ID			 0xEF4014

#define FLASH_W25Q8_MAX_ADDR		0x0FFFFF
#define FLASH_W25Q16_MAX_ADDR		0x1FFFFF
#define FLASH_W25Q32_MAX_ADDR		0x3FFFFF
#define FLASH_W25Q64_MAX_ADDR		0x7FFFFF
#define FLASH_W25Q128_MAX_ADDR		0xFFFFFF
#define FLASH_W25Q256_MAX_ADDR		0x1FFFFFF

void SPI_FLASH_Init(void);
int8_t  SPI_FLASH_EraseSector(uint32_t SectorAddr);
int8_t  SPI_FLASH_EraseBulk(void);
int8_t  SPI_FLASH_WriteData(uint32_t uwStartAddress, uint8_t* pData, uint32_t uwDataSize);
int8_t  SPI_FLASH_ReadData(uint32_t uwStartAddress, uint8_t* pData, uint32_t uwDataSize);
uint32_t SPI_FLASH_ReadID(void);

#ifdef __cplusplus
    }
#endif
#endif /* _SPI_FLASH_H */
